using System;
using System.Threading;
using LegoBotPrimaTests.Utils;
using Moq;
using Timer = System.Timers.Timer;

namespace LegoBotPrimaTests
{
    public abstract class BaseFixture
    {

        #region Generic Mock
        protected static T GetMock<T>() where T : class
        {
            return GetMock<T>(m => { }, o => { });
        }
        protected static T GetMock<T>(Action<Mock<T>> setupMock) where T : class
        {
            return GetMock(setupMock, o => { });
        }
        protected static T GetMock<T>(Action<T> setupObject) where T : class
        {
            return GetMock(m => { }, setupObject);
        }
        protected static T GetMock<T>(Action<Mock<T>> setupMock, Action<T> setupObject) where T : class
        {
            var mock = new Mock<T>();
            setupMock(mock);
            var obj = mock.Object;
            setupObject(obj);
            return obj;
        }
        #endregion



        protected static bool RunDelayed(int milliseconds, Action<ManualResetEvent> action, params DelayedAction[] actions)
        {
            var reset = new ManualResetEvent(false);

            if(actions.Length > 0)
            {
                var currentIndex = 0;
                var timer = new Timer { Interval = actions[0].Deley };
                timer.Elapsed += (o, e) =>
                                     {
                                         currentIndex++;
                                         if(currentIndex <= actions.Length)
                                         {
                                             actions[currentIndex - 1].Action(reset);
                                             if (currentIndex < actions.Length)
                                                 timer.Interval = actions[currentIndex].Deley;
                                         }
                                         if(currentIndex >= actions.Length)
                                         {
                                             timer.Enabled = false;
                                             reset.Set();
                                         }
                                     };
                timer.Enabled = true;
            }

            action(reset);

            var end = DateTime.Now.AddMilliseconds(milliseconds);
            var result = false;
            while ((!result) && (DateTime.Now < end))
            {
                result = reset.WaitOne(0);
            }
            return result;
        }

    }
}